// 主席树 可持久化权值线段树
// https://www.luogu.com.cn/problem/P3834
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
using ll = long long;
using T = int;
T rad(); // quick read
const int inf = 0x3f3f3f3f;
#define rf(i, n) for (int i = 1; i <= (n); ++i)
const int maxn = 5 + 2e5;

int n, m;
int a[maxn];

struct Seg {
  private:
    int tot;
    int val[maxn << 5]; // cnt
    int ch[maxn << 5][2];

    int new_node(int x) { return val[++tot] = x, ch[tot][0] = 0, ch[tot][1] = 0, tot; }
    void maintain(int u) { val[u] = val[ch[u][0]] + val[ch[u][1]]; }
    int cp(int u) { return val[++tot] = val[u], ch[tot][0] = ch[u][0], ch[tot][1] = ch[u][1], tot; }

  public:
    int build(int l, int r) {
        int u = new_node(0);
        if (l == r) return u;
        int mid = l + r >> 1;
        ch[u][0] = build(l, mid);
        ch[u][1] = build(mid + 1, r);
        return u;
    }

    int update(int u, int l, int r, int pos, int x) {
        u = cp(u);
        if (l == r) {
            val[u] += x;
            return u;
        }

        int mid = l + r >> 1;
        if (pos <= mid)
            ch[u][0] = update(ch[u][0], l, mid, pos, x);
        else
            ch[u][1] = update(ch[u][1], mid + 1, r, pos, x);
        maintain(u);
        return u;
    }

    int ask(int u, int v, int l, int r, int k) {
        if (l == r) return l;
        int mid = l + r >> 1;
        int cnt = val[ch[v][0]] - val[ch[u][0]]; // 前缀差分，获得区间
        if (cnt >= k)
            return ask(ch[u][0], ch[v][0], l, mid, k);
        else
            return ask(ch[u][1], ch[v][1], mid + 1, r, k - cnt);
    }
} seg;
int root[maxn], rsiz;

int decoder[maxn], dsiz;
void init_decoder() { // 离散化
    dsiz = n;
    rf(i, n) decoder[i] = a[i];
    sort(decoder + 1, decoder + 1 + dsiz);
    dsiz = unique(decoder + 1, decoder + 1 + dsiz) - decoder - 1;
}
inline int coder(int x) { return lower_bound(decoder + 1, decoder + 1 + dsiz, x) - decoder; }

int main() {
    // freopen("main.in", "r", stdin);
    n = rad(), m = rad();
    rf(i, n) a[i] = rad();
    init_decoder();
    root[0] = seg.build(1, dsiz);
    rf(i, n) root[rsiz + 1] = seg.update(root[rsiz], 1, dsiz, coder(a[i]), 1), rsiz++;
    rf(i, m) {
        int l = rad(), r = rad(), k = rad();
        printf("%d\n", decoder[seg.ask(root[l - 1], root[r], 1, dsiz, k)]);
    }
}

T rad() {
    T back = 0;
    int ch = 0, posi = 0;
    for (; ch < '0' || ch > '9'; ch = getchar())
        posi = ch ^ '-';
    for (; ch >= '0' && ch <= '9'; ch = getchar())
        back = (back << 1) + (back << 3) + (ch & 0xf);
    return posi ? back : -back;
}